package com.codemeta.bokit.mybatis.core.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codemeta.bokit.mybatis.core.kit.MyBatisKit;
import com.codemeta.bokit.mybatis.core.page.PageX;
import org.apache.ibatis.annotations.Param;

import java.util.Objects;

/**
 * mybatis-plus基础mapper对象
 *
 * @author hice
 * @date 2021/11/19
 */
public interface BaseMapperX<T> extends BaseMapper<T> {

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param pageX   分页查询条件（可以为 RowBounds.DEFAULT）
     * @param wrapper 实体对象封装操作类（可以为 null）
     * @return .
     */
    default Page<T> selectPageX(PageX pageX, @Param(Constants.WRAPPER) Wrapper<T> wrapper) {
        // MyBatis Plus 查询
        Page<T> page = MyBatisKit.buildPage(pageX);
        selectPage(page, wrapper);
        // 转换返回
        return page;
    }

    /**
     * 第一条记录
     *
     * @param wrapper .
     * @return .
     */
    default T first(QueryWrapper<T> wrapper) {
        wrapper.last("limit 1");
        return selectOne(wrapper);
    }

    /**
     * 第一条记录
     *
     * @param wrapper .
     * @return .
     */
    default T first(LambdaQueryWrapper<T> wrapper) {
        wrapper.last("limit 1");
        return selectOne(wrapper);
    }

    /**
     * 最后一条记录
     *
     * @param wrapper .
     * @return .
     */
    default T last(QueryWrapper<T> wrapper) {
        Long count = selectCount(wrapper);
        if (Objects.nonNull(count) && count > 0) {
            if (count != 1) {
                wrapper.last(String.format("limit %s,1", count - 1));
            }
            return selectOne(wrapper);
        }
        return null;
    }

    /**
     * 最后一条记录
     *
     * @param wrapper .
     * @return .
     */
    default T last(LambdaQueryWrapper<T> wrapper) {
        Long count = selectCount(wrapper);
        if (Objects.nonNull(count) && count > 0) {
            if (count != 1) {
                wrapper.last(String.format("limit %s,1", count - 1));
            }
            return selectOne(wrapper);
        }
        return null;
    }

}